#include "stdafx.h"
#include "collisionhandler.h"
#include "vec2.h"
#include "mage.h"
#include "potion.h"
#include "spell.h"
#include "scene.h"

CollisionHandler::CollisionHandler(Scene *scene) :
    _scene(scene)
{
    reset();
}

CollisionHandler::~CollisionHandler()
{
}

void CollisionHandler::reset()
{
    _state = State_INITIAL;
    _mage = 0;
    _potion = 0;
    _spell = 0;
}

void CollisionHandler::visit(Mage *mage)
{
    if (_state == State_INITIAL) {
        _mage = mage;
        _state = State_FIRST_VISITED;
    } else if (_state == State_FIRST_VISITED) {
        if (_mage)
            handle(_mage, mage);
        else if (_potion)
            handle(mage, _potion);
        // TODO: add scene processing
        _state = State_SECOND_VISITED;
    }
}

void CollisionHandler::visit(Potion *potion)
{
    if (_state == State_INITIAL) {
        _potion = potion;
        _state = State_FIRST_VISITED;
    } else if (_state == State_FIRST_VISITED) {
        if (_mage)
            handle(_mage, potion);
        // TODO: add scene processing
        _state = State_SECOND_VISITED;
    }
}

void CollisionHandler::visit(Spell *spell)
{
    if (_state == State_INITIAL) {
        _spell = spell;
        _state = State_FIRST_VISITED;
    } else if (_state == State_FIRST_VISITED) {
        // TODO: add scene processing
        _state = State_SECOND_VISITED;
    }
}

void CollisionHandler::handle(Mage *first, Mage *second)
{
    vec2f fpos(first->x(), first->y());
    vec2f spos(second->x(), second->y());
    vec2f diff = fpos - spos;
    float reqDist = first->radius() + second->radius();
    float currDist = diff.getLength();
    float offset = 0.5 * (reqDist - currDist);

    diff = diff.normalize();
    diff *= offset;
    first->move(diff.x, diff.y);
    second->move(-diff.x, -diff.y);
}

void CollisionHandler::handle(Mage *mage, Potion *potion)
{
    mage->drink(potion);
    _scene->deleteObject(potion);
}
